package com.binhthuan.catechist.client.form;

import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import com.binhthuan.catechist.client.ECApplication;
import com.binhthuan.catechist.client.ECIcons;
import com.binhthuan.catechist.client.data.callback.DSCallback;
import com.google.gwt.event.shared.HandlerRegistration;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
import com.smartgwt.client.widgets.grid.events.DataArrivedEvent;

public class AbstractForm extends DynamicForm implements IForm {

    private Vector<UpdateSuccessHandler> updateSuccessHandlers = new Vector<UpdateSuccessHandler>();
    private Vector<UpdateFailureHandler> updateFailureHandlers = new Vector<UpdateFailureHandler>();

    public AbstractForm() {
        setAutoFocus(true);
        setWrapItemTitles(false);
        // setFixedColWidths(true);
        setShowInlineErrors(true);
        setErrorsPreamble("");
        setErrorItemCellStyle("error");
        setValidateOnExit(true);
    }

    /**
     * 
     */
    public AbstractForm(DataSource dataSource) {
        this();
        setDataSource(dataSource);
    }

    /**
     * Prepare to edit a new record. Subsequent calls to saveData() will use an
     * add rather than an update operation.
     * 
     * @param resetField
     *            <b>false</b> - Keep current values of all fields.
     */
    public void editNewRecord(boolean resetField) {
        if (resetField) {
            editNewRecord();
        } else {
            Map<Object, Object> initialValues = new HashMap<Object, Object>();
            FormItem[] fields = getFields();
            FormItem field = null;

            for (int i = 0; i < fields.length; i++) {
                field = fields[i];
                if (field.getValue() != null) {
                    initialValues.put(field.getName(), field.getValue());
                }
            }

            editNewRecord(initialValues);
        }
    }

    public void saveClick() {
        saveData(new DSCallback() {

            @Override
            public void onSuccess() {
                onUpdateSuccess();
            }

            @Override
            public void onFailure(DSResponse response, Object rawData) {
                onUpdateFailure(response, rawData);
            }
        });
        fireEvent(new DataArrivedEvent(null));
    }

    protected void onUpdateSuccess() {
        for (UpdateSuccessHandler handler : updateSuccessHandlers) {
            handler.onSuccess();
        }
    }

    protected void onUpdateFailure(DSResponse response, Object rawData) {
        for (UpdateFailureHandler handler : updateFailureHandlers) {
            handler.onFailure(response, rawData);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.smartgwt.client.widgets.form.DynamicForm#setValue(java.lang.String,
     * java.lang.String)
     */
    @Override
    public void setValue(String fieldName, String value) {
        getItem(fieldName).setValue(value);
    }

    /**
     * Tạo nút Save để submit form, mặc định colSpan=2, width=100.
     * 
     * @return
     */
    public ButtonItem createSaveButton() {
        ButtonItem saveButton = new ButtonItem();
        saveButton.setTitle(ECApplication.getConstants().save());
        saveButton.setIcon(ECIcons.getIcon("save.png"));
        saveButton.setAlign(Alignment.CENTER);
        saveButton.setColSpan(2);
        saveButton.setWidth(100);
        saveButton.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                saveClick();
            }
        });

        return saveButton;
    }

    @Override
    public HandlerRegistration addUpdateFailureHandler(final UpdateFailureHandler handler) {
        assert updateFailureHandlers != null;
        updateFailureHandlers.add(handler);
        return new HandlerRegistration() {

            @Override
            public void removeHandler() {
                updateFailureHandlers.remove(handler);
            }
        };
    }

    @Override
    public HandlerRegistration addUpdateSuccessHandler(final UpdateSuccessHandler handler) {
        assert updateSuccessHandlers != null;
        updateSuccessHandlers.add(handler);
        return new HandlerRegistration() {

            @Override
            public void removeHandler() {
                updateSuccessHandlers.remove(handler);
            }
        };
    }
}
